package chen.huai.jie.spring.xmlconfig.db.hibernate.repository;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.List;

public abstract class BaseRepository<T> {

    protected abstract Class<T> getEntityClass();

    @Autowired(required = false)
    private SessionFactory sessionFactory;

    private Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    public Serializable save(T entity) {
        return getCurrentSession().save(entity);
    }

    protected void uodate(T entity) {
        getCurrentSession().update(entity);
    }

    protected void saveOrUpdate(T entity) {
        getCurrentSession().saveOrUpdate(entity);
    }

    protected void delete(Serializable id) {
        getCurrentSession().delete(find(id));
    }

    protected T find(Serializable id) {
        return getCurrentSession().get(getEntityClass(), id);
    }

    protected List<T> findAll() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(" from ").append(getEntityClass().getSimpleName());
        String hql = stringBuilder.toString();
        return find(hql);
    }

    protected List<T> find(String hql) {
        return getCurrentSession().createQuery(hql).list();
    }

    protected List<T> find(String hql, Object... params) {
        Query<T> query = getCurrentSession().createQuery(hql);
        for (int i = 0, len = params.length; i < len; i++) {
            query.setParameter(i + "", params[i]);
        }
        return query.list();
    }

    protected List<T> findByPage(String hql, int pageNo, int pageSize, Object... params) {
        Query<T> query = getCurrentSession().createQuery(hql);
        if (params.length > 0) {
            for (int i = 0, len = params.length; i < len; i++) {
                query.setParameter(i + "", params[i]);
            }
        }
        return query.setFirstResult((pageNo - 1) + pageSize).setMaxResults(pageSize).list();
    }

    protected long count(String countHql, Object... params) {
        Query<T> query = getCurrentSession().createQuery(countHql);
        if (params.length > 0) {
            for (int i = 0, len = params.length; i < len; i++) {
                query.setParameter(i + "", params[i]);
            }
        }
        return (long) query.getSingleResult();
    }
}
